/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cmti.skeleton.service.impl;

import com.cmti.commons.entity.AuthenticationInfo;
import com.cmti.commons.exception.service.AccountNotFoundException;
import com.cmti.commons.exception.service.IncorrectPasswordException;
import com.cmti.commons.exception.service.ServiceException;
import com.cmti.commons.util.EncryptUtil;
import com.cmti.commons.util.StringUtils;
import com.cmti.skeleton.dao.mapper.SysRightsMapper;
import com.cmti.skeleton.dao.mapper.SysUserMapper;
import com.cmti.skeleton.dto.SysUserDto;
import com.cmti.skeleton.dto.TreeNode;
import com.cmti.skeleton.entity.SysRights;
import com.cmti.skeleton.entity.SysUser;
import com.cmti.skeleton.service.RoleService;
import com.cmti.skeleton.service.SysLogService;
import com.cmti.skeleton.service.UserService;
import com.github.pagehelper.PageHelper;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Danny Lee
 */
@Service
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {

    private final Log log = LogFactory.getLog(this.getClass());
    @Autowired
    SysUserMapper userMapper;
    @Autowired
    SysRightsMapper rightMapper;
    @Autowired
    SysLogService sysLogService;
    @Autowired
    RoleService roleService;

    /**
     * 登录验证
     *
     * @param account
     * @param password
     * @return
     *
     */
    @Override
    public AuthenticationInfo authenticate(String account, String password) {
        // 查找用户
        SysUser authInfo = null;
        authInfo = userMapper.selectByAccount(account);

        if (authInfo == null) {
            throw new AccountNotFoundException("找不到对应的用户信息！");
        } else {
            if (!EncryptUtil.encryptMD5(password).equals(authInfo.getPassword())) {
                throw new IncorrectPasswordException("密码错误!");
            } else if (authInfo.getStatus() == 1) {
                throw new ServiceException("该用户已被冻结！");
            }
        }

        return authInfo;
    }

    /**
     * 生成树状节点
     *
     * @param userId
     * @param rightParent
     * @param menuParent
     * @param resultMap
     *
     *
     */
    private void genChildTreeNode(long userId, TreeNode rightParent, TreeNode menuParent, Map<String, List> resultMap) {
        List<SysRights> rightsList = resultMap.get("rightsList");
//        List<TreeNode> rightsTree = resultMap.get("rightsTree");
//        List<TreeNode> navMenuTree = resultMap.get("navMenuTree");

        List<TreeNode> rightChildren = new LinkedList<>();
        rightParent.setChildren(rightChildren);
        List<TreeNode> menuChildren = null;
//        if (menuParent != null) {
//            menuChildren = new LinkedList<TreeNode>();
//            menuParent.setChildren(menuChildren);
//        }

        List<SysRights> rl = rightMapper.selectByUserIdAndParentId(userId, rightParent.getId());

        for (SysRights sr : rl) {
            // 添加权限List
            rightsList.add(sr);

            // 添加权限树
            TreeNode rightTreeNode = new TreeNode(sr.getId(), sr.getName(), false, null);
            rightChildren.add(rightTreeNode);

            // 添加导航菜单树
            TreeNode menuTreeNode = null;
            if (sr.getType() == 0) {
                // 如果还没初始化menuChildren, 则初始化
                if (menuParent != null && menuChildren == null) {
                    menuChildren = new LinkedList<TreeNode>();
                    menuParent.setChildren(menuChildren);
                }
                if (menuChildren != null) {
                    menuTreeNode = new TreeNode(sr.getId(), sr.getName(), false, null);
                    if (StringUtils.isNotNull(sr.getUrl())) {
                        Map<String, Object> attrs = new HashMap<String, Object>();
                        attrs.put("url", sr.getUrl());
                        menuTreeNode.setAttributes(attrs);
                    }
                    menuChildren.add(menuTreeNode);
                }
            }

            // 递归调用本方法
            genChildTreeNode(userId, rightTreeNode, menuTreeNode, resultMap);
        }
    }

    /**
     * 生成权限和菜单
     *
     * @param authInfo
     * @return
     */
    @Override
    public Map<String, List> generateRightsAndMenu(AuthenticationInfo authInfo) {
        Map<String, List> map = new HashMap<>();

        Map<String, Long> params = new HashMap<>(2);
        params.put("uid", authInfo.getId());
        params.put("pid", 0L);
        List<SysRights> rl = rightMapper.selectByUserIdAndParentId(authInfo.getId(), 0);
        // 权限List（AuthenticationInfo里面用）；key：rightsList
        List<SysRights> rightsList = new LinkedList(rl);
        // 分级权限树List（权限配置里面用）；key：rightsTree
        List<TreeNode> rightsTree = new LinkedList();
        // 导航菜单树List；key：navMenuTree
        List<TreeNode> navMenuTree = new LinkedList();
        map.put("rightsList", rightsList);
        map.put("rightsTree", rightsTree);
        map.put("navMenuTree", navMenuTree);
        for (SysRights sr : rl) {
            TreeNode rightTreeNode = new TreeNode(sr.getId(), sr.getName(), false, null);
            rightsTree.add(rightTreeNode);

            TreeNode menuTreeNode = null;
            if (sr.getType() == 0) {
                menuTreeNode = new TreeNode(sr.getId(), sr.getName(), false, null);
                // 一级菜单, 添加不同的图标
                switch (sr.getId().intValue()) {
                    case 1:
                        menuTreeNode.setIconCls("icon-wrench");
                        break;
                }
                if (StringUtils.isNotNull(sr.getUrl())) {
                    Map<String, Object> attrs = new HashMap<>();
                    attrs.put("url", sr.getUrl());
                    menuTreeNode.setAttributes(attrs);
                }
                navMenuTree.add(menuTreeNode);
            }

            genChildTreeNode(authInfo.getId(), rightTreeNode, menuTreeNode, map);
        }

        return map;
    }

    /**
     * 获取用户集合
     *
     * @param dto
     * @return the java.util.List&lt;com.cmti.skeleton.dto.SysUserDto&gt;
     */
    @Override
    public List<SysUserDto> getUserList(SysUserDto dto) {
//        throw new RuntimeException("test");
        PageHelper.startPage(dto.getPage(), dto.getRows());
        return userMapper.selectListByDto(dto);
    }

    /**
     * 根据id 获取用户信息
     *
     * @param userId
     * @return 成功返回实体,失败返回null
     *
     */
    @Override
    public SysUser getSysUserById(long userId) {
        SysUser user = userMapper.selectByPrimaryKey(userId);//根据id 获取用户信息
        return user;
    }

    /**
     * 添加用户 及 角色信息
     *
     * @param userDto the value of userDto
     * @return the boolean
     */
    @Transactional
    @Override
    public boolean addUser(SysUserDto userDto) {
        userDto.setPassword(EncryptUtil.encryptMD5(userDto.getPassword()));
        int rc = userMapper.insertSelective(userDto);
        this.addUserRole(userDto);
        return rc == 1;

    }

    /**
     * 添加用户角色
     *
     * @param userDto the value of userDto
     */
    @Transactional
    public void addUserRole(SysUserDto userDto) {
        long uid = userDto.getId();
        for (String rid : userDto.getRoleId()) {
            userMapper.insertUserRole(uid, Long.valueOf(rid));
        }
    }

    /**
     * 修改用户并添加角色信息
     *
     * @param user
     * @return the boolean
     *
     */
    @Transactional
    @Override
    public boolean modifyUser(SysUserDto user) {

        this.delUserRole(user.getId());
        userMapper.updateByPrimaryKeySelective(user);
        this.addUserRole(user);
        return true;
    }

    /**
     * 删除用户和角色信息中间表 本方法不定义对外接口
     *
     * @param userId
     * @return 更新的行数
     */
    private int delUserRole(Long userId) {
        return userMapper.deleteUserRoles(userId);

    }

    /**
     * 验证用户帐号是否重复
     *
     * @param account
     * @return 如果存在则返回1，否则返回0
     */
    @Override
    public long getValidCount(String account) {
        return userMapper.selectByAccount(account) == null ? 0 : 1;
    }

    /**
     * 重置密码
     *
     * @param userId
     * @param newPwd
     */
    @Transactional
    @Override
    public void resetPassword(long userId, String newPwd) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setPassword(EncryptUtil.encryptMD5(newPwd));
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 删除用户
     *
     * @param uid
     * @return
     */
    @Transactional
    @Override
    public boolean delUser(long uid) {
        delUserRole(uid);
        return userMapper.deleteByPrimaryKey(uid) == 1;
    }

    /**
     * 激活或锁定用户
     *
     * @param uid
     * @param action
     */
    @Override
    @Transactional
    public void lockOrUnlock(long uid, String action) {
        SysUser user = new SysUser();
        user.setId(uid);
        if ("lock".equals(action)) {
            user.setStatus(1);
        } else if ("unlock".equals(action)) {
            user.setStatus(0);
        }
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public List<Long> getRoleIdByUserId(Long uid) {
        return userMapper.selectRoleIdByUserId(uid);

    }
}
